package com.sdzee.meteocal.servlets;

import java.io.IOException;
import java.net.MalformedURLException;




import net.aksingh.owmjapis.DailyForecast;
import net.aksingh.owmjapis.OpenWeatherMap;
import net.aksingh.owmjapis.DailyForecast.Forecast;
import net.aksingh.owmjapis.DailyForecast.Forecast.Temperature;

import org.json.JSONException;




import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.sdzee.beans.Homepage;
import com.sdzee.dao.*;

import javax.servlet.annotation.*;

import model.*;

import java.util.List;

import net.aksingh.owmjapis.CurrentWeather;
import net.aksingh.owmjapis.DailyForecast;
import net.aksingh.owmjapis.DailyForecast.Forecast.Temperature;
import net.aksingh.owmjapis.OpenWeatherMap;
import net.aksingh.owmjapis.DailyForecast.Forecast;

import org.json.JSONException;

@SuppressWarnings("serial")               
@WebServlet("/homePageServlet")            
public class HomePageServlet extends HttpServlet {          
	
	static final float MIN_TEMP = 80;   
	static final float MAX_TEMP= 82;
	
	// per il already exist()     
	@EJB           
	private UserDaoEJB uDAO ;
	@EJB
	private InvitationDaoEJB iDAO ;
	@EJB
	private NotificationDaoEJB nDAO ;
	@EJB
	private EventDaoEJB eDAO ;
	
	public  HomePageServlet() {
        super();
        
    	uDAO=new UserDaoEJB() ;
    
    	iDAO=new InvitationDaoEJB() ;
    	
    	nDAO=new NotificationDaoEJB();
    	
        eDAO=new EventDaoEJB() ;
    }

      public void doGet ( HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
	
    	// traitement des donne entre par le user nella homePage
  		
  	    String unDesChoix =  request.getParameter("unDesChoix");
  	    String password = request.getParameter("Password");
  	    String pseudo = request.getParameter("Pseudo");
  	    String newEmail = request.getParameter("NewEmail");
  	    String newPassword =  request.getParameter("NewPassword");
  	    String newPseudo =   request.getParameter("NewPseudo");
  	    
  	    String message="test";
  	    // ancore a gerer le NULL pointer exception en cas de non choix !
  	    /*verification du choix de l user : log in ? */
  	    
  	    if( unDesChoix !=null ){
  	    
  	    if ( unDesChoix.equals("LogIn") ) {
  	    	
  	    /* initialisation du message a afficher : si un des champs obligatoires du formulaire
  	     *  n est pas renseigne ou L' USER EXISTE DEJA  OU LA MAIL SBAGLIATA alors on affiche un message d erreur, sinon on affiche un message de succès 
  	     *  ... nous reviendrons dessus*/
  	    	
  	    	// ceci est uniquement la logique de controle ke les champs onligatoire sont renseigné..a revoir apres gestionDB
     	if ( pseudo.trim().isEmpty() || password.trim().isEmpty() || uDAO.notExistBis(pseudo, password)) {
  	    		
  	    		message = " erreur -some field aren't fulfilled or y're not a regular user, please registrate or turn back. <br> <a "
  	    				+ "href=\"homePageServletUrl\">click here </a> to turn back.";
  	    	} else {
   	    		// puntare direttamente all pagina personale..vedremmo dopo !
  	    		
  	    		//les deux tables de la page personelle
  	    		List<Event> eventCreated = eDAO.findEventsCreator(pseudo);
  	    		List<Event> invitationAccepted = iDAO.findInvitationAccepted(pseudo);
  	    		
  	    		
  	    		
  	    		
  	    		
  	    	    //Calcule de la notification du message_Alert, and fulfilling the Notification Table prima di findmynotifcations()
  	    		
  	    		String eventAbout, messageAlert_Invitation, userDestinatore;
  	    		Date currentDateComputer = new Date();
  	    		
  	    		for( Event item: invitationAccepted){
  	    			
  	    			Date dateEvent = item.getDate();
  	    			float vet[]= {0,0};
  	    			
  	    			if(  badWeather(dateEvent, item.getPlace()) && item.getIndoor_outdoor().equals("no") && oneDayAfter(dateEvent, currentDateComputer) ){
  	    				vet = getTemp(item.getPlace());
  	            	    userDestinatore =pseudo;
  	            	    messageAlert_Invitation ="Sorry " + pseudo + " , the METEO announce bad weather for the Tomorrow Event: " + item.getName()
  	            	    		+ ". TempMax ="+ vet[0] + " and tempMin="+ vet[1] + " /F°" ;
  	            	    eventAbout = "none";
  	                    nDAO.add(eventAbout, messageAlert_Invitation, userDestinatore); 
  	                    
  	                    
  	    			
  	    			}
  	            }
  	    		
  	    		
  	    		//gestion du voyant de notifications
  	    		List<Notification> notif = nDAO.findMyNotifications(pseudo);
  	    		if(!notif.isEmpty()){
  	    			String youHaveNewNotification = "you have some new NOTIFICATIONS, please read it !! <br> ";
  	    					request.setAttribute("youHaveNewNotification", youHaveNewNotification);
  	    			
  	    		}
  	    		//fin gestion du voyant
  	    		
  	    	
  	    		
  	  	    		
  	    		request.setAttribute("events", eventCreated);
  	    		request.setAttribute("invitatedEvents", invitationAccepted);
  	    		
  	    		//pour rester dans la contexte pseudo, je dois le faire suivre.
  	    		request.setAttribute("pseudo", pseudo);
  	    		
  	    		
  	    	//calcolo della temperautra in °F per ogni Event   	    		
  	    		Map<Event, Long> tempsMaxE = new HashMap<Event,Long>();   
  	    		Map<Event,Long> tempsMinE = new HashMap<Event,Long>();
  	    		Map<Event, Long> tempsMaxI = new HashMap<Event,Long>();  
  	    		Map<Event, Long> tempsMinI = new HashMap<Event,Long>();
            	
                for( Event item: eventCreated){     
  	    			
                	float vet[]= getTemp(item.getPlace());
                	
                	tempsMaxE.put(item,(long)vet[0]);   
                	tempsMinE.put(item,(long)vet[1]);                    
  	            }              
  	    		
                for( Event item: invitationAccepted){
  	    			
                    float vet[]= getTemp(item.getPlace());
                	         
                	 tempsMaxI.put(item,(long)vet[0]);                      
                	 tempsMinI.put(item,(long)vet[1]);    
                	 
  	            }
  	    		
  	    		//Temperatures
  	    		request.setAttribute("tempsMaxE", tempsMaxE);
  	    		request.setAttribute("tempsMinE", tempsMinE);
  	    		request.setAttribute("tempsMaxI", tempsMaxI);
  	    		request.setAttribute("tempsMinI", tempsMinI);
  	    		
  	    		
  	    		
  	    		
  	    		
  	    		
  	    		
  	    		
  	    		
  	    		this.getServletContext().getRequestDispatcher("/WEB-INF/PersonalPage.jsp").forward( request, response );
  	    	}
  	    }
  	    
  	    /* verification du second choix de l user : registration ? */
  	    
  	    if( unDesChoix.equals("NewRegistration") ) {
  	    	
  	    	// traiter la nouvelle registration
  	   // ceci est uniquement la logique de controle ke les champs onligatoire sont renseigné..a revoir apres gestionDB
              if ( newEmail.trim().isEmpty() || newPassword.trim().isEmpty() || newPseudo.trim().isEmpty() ) {
  	    		
  	    		message = " error you didn't fullfil all the manadatory field----. <br> <a "
 	    				+ "href=\"homePageServletUrl\">retry here</a> "; 	    		
  	    	  } else {
              
              
              
              if( uDAO.notExist(newPseudo) ) {
            	 //le creer..
            	  uDAO.add( prepareUser(newEmail, newPassword, newPseudo));
            	// puntare direttamente all pagina personale..vedremmo dopo !!
            	  
            	  request.setAttribute("pseudo", newPseudo);
    	    		this.getServletContext().getRequestDispatcher("/WEB-INF/PersonalPage.jsp").forward( request, response );            	 
              }
              
              else {
            	  // user already exist....            	  
            	  message = " The user already exist. <br> <a "
     	    				+ "href=\"homePageServletUrl\">try a new user </a>";              	   
  	    	    } 
  	    	
  	         } 
  	    
  	    }
  	   
  	  } else {
  		  message =" error-LogIn o NEWRegistration ?? you didn'nt choose. Click <br> <a "
				+ "href=\"homePageServletUrl\">here</a> to retry.";
  		  
  		
  	  }    
  	    /* Creation du beans Client et initialisation avec avec les donnèes récupérées */
  	
  	    Homepage homepage = new Homepage();
  	    homepage.setUnDesChoix(unDesChoix);
  	    homepage.setPassword(password);
  	    homepage.setNewPassword(newPassword);
  	    
  	 
  	    /* ajout du beans et du message a l'objet requète*/
  	    
  	    request.setAttribute("homepage", homepage);
  	    request.setAttribute("message", message);
  	    
  	    /* transmission a la page JSP en charge de l affichage des donnees */
  	   
  			this.getServletContext().getRequestDispatcher("/WEB-INF/afficherUser.jsp").forward( request, response );
  		
  	    
  		       
  	}
            
      
      public User prepareUser(String em, String pa, String ps){
    	  User user = new User();
    	  user.setMail(em);
    	  user.setPassword(pa);
    	  user.setPseudo(ps);
    	  return user; 
      }
	
      @SuppressWarnings("deprecation")
	public boolean badWeather(Date dateEvent, String place)throws IOException, MalformedURLException, JSONException{
    	 
    	 float tempMin=10, tempMax=20 ;
    	 OpenWeatherMap owm = new OpenWeatherMap(""); 		
 	     DailyForecast df = owm.dailyForecastByCityName(place, Byte.parseByte("5"));
    	 //Interroger OWN par rapport a date dateEvent si disponible , a defaut la function doit renvoyer tjrs false
    	  
 	    if (!df.isValid()) {
 	    	
            return false;
        } else {
                                 
            Forecast forecastList = df.getForecastInstance(1);
            Temperature temp = forecastList.getTemperatureInstance();
            
           
            
            

            
                DailyForecast.Forecast forecast = df.getForecastInstance(1);

                
                if (forecast.hasDateTime()) {
                    // here is getDateTime() function
                	if(   ( ( forecast.getDateTime().getDay() %7 ) == ((dateEvent.getDay())%7) ) && 
                			( forecast.getDateTime().getMonth() == dateEvent.getMonth() ) && 
                			( forecast.getDateTime().getYear() == dateEvent.getYear() )   ){
                		
                		 tempMin = temp.getMaximumTemperature();
                         tempMax = temp.getMinimumTemperature();
                         
                         if( !( (MIN_TEMP <= tempMin) && (tempMax <= MAX_TEMP) ) ){ 
                   		  return true;
                   	  }else {
                   		  return false;           
                   		  }
                	}
                	
                } 		
                
                	 
               
            }
        
        
 
 	     
    	  
    	 
    	  return false ;
      }
      public float[] getTemp(String place) throws IOException, MalformedURLException, JSONException{
    	  
    	
     	 OpenWeatherMap owm = new OpenWeatherMap(""); 		
  	     DailyForecast df = owm.dailyForecastByCityName(place, Byte.parseByte("5"));
  	     Forecast forecastList = df.getForecastInstance(1);
         Temperature temp = forecastList.getTemperatureInstance();
         DailyForecast.Forecast forecast = df.getForecastInstance(1);
         
         if (forecast.hasDateTime()) {
        float vet[] = {temp.getMaximumTemperature(), temp.getMinimumTemperature() };
         		return vet; 
         	}
		return null;
      }
      @SuppressWarnings("deprecation")
	public boolean oneDayAfter (Date dateEvent, Date currentDateComputer) {
    	  
    	  if(dateEvent.getYear() == currentDateComputer.getYear() ){
    		  if(dateEvent.getMonth() == currentDateComputer.getMonth()){
    			  if( ( dateEvent.getDay()%7 ) == (currentDateComputer.getDay() + 1)%7 ){
    				  return true;
    			  }
    		  }
    	  }
    	  return false;
      }
        
          
   

	

	
}
